结构模式-组合模式
组合模式是什么?
组合模式:将对象组合成树形结构表示:“部分-整体” 的层次结构(组合模式使得用户对单个对象和组合对象的使用具有一致性)
classDiagram
Client --> Component
Component <|-- Leaf
Component <|-- Composite
Composite o--> Component
Component: +add(Component)
Component: +remove(Component)
Component: +display()
Composite: +add(Component)
Composite: +remove(Component)
Composite: +display()
Leaf: +display()
说白了,就是用来存储树型结构的数据的模式
graph TD
aComposite --> aLeaf
aComposite --> bLeaf
aComposite --> bComposite
aComposite --> cLeaf
bComposite --> cComposite
bComposite --> dLeaf
cComposite --> eLeaf
cComposite --> fLeaf
cComposite --> gLeaf
Golang 的组合
Golang 其实与 Java 的继承有很多不同,并不能简单的理解为继承、多态、重写这几个功能的不同实现方式,实际上,Golang 是提倡共用组合与接口,如下代码所示:
package main
import (
"fmt"
)
// 注意,这里定义了一个接口
type IHello interface {
Hello(name string)
}
type A struct {
}
func (*A) Hello(name string) {
fmt.Println("hello " + name + ", i am a")
}
type D struct {
}
func (*D) Hello(name string) {
fmt.Println("hello " + name + ", i am d")
}
type B struct {
IHello
}
func (*B) Hello(name string) {
fmt.Println("hello " + name + ", i am b")
}
type C struct {
IHello
}
func main() {
name := "Lee"
a := A{}
a.Hello(name) //hello Lee, i am a
b := B{&A{}}
b.Hello(name) //hello Lee, i am b
b.IHello.Hello(name) //hello Lee, i am a
c := C{&A{}}
c.Hello(name) //hello Lee, i am a
c.IHello = &D{}
c.Hello(name) //hello Lee, i am d
}
- A 的指针继承了接口 IHello
- B,C 中嵌入了接口 IHello,
- B C两者在赋值时,同时可以根据运行时上下文指定其他具体实现,比如D,更加灵活。
golang从语言级别对组合做了充分的语法糖,使得组合更加高效。我来看一段 java 的组合实现
public interface IHello {
public void hello();
}
public class A implements IHello {
@Override
public void hello() {
System.out.println("Hello, I am A.");
}
}
public class B implements IHello {
@Override
public void hello() {
System.out.println("Hello, I am B.");
}
}
public class C {
IHello h;
public void hello() {
h.hello();
}
}
public static void main(String args[]) {
C c = new C();
c.h = new A();
c.hello();
c.h = new B();
c.hello();
}
例中类 C 组合了接口 IHello, 如需暴露 IHello 的方法则需要添加一个代理方法
public void hello() {
h.hello();
}
这样在代码量上会多于继承方式。golang 中无需额外代码即可提供支持。